package wzw.swing.calendar;
 

import java.awt.BorderLayout;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;

import javax.swing.BorderFactory;
import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.ComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup;
import javax.swing.plaf.metal.MetalComboBoxUI;

import com.sun.java.swing.plaf.motif.MotifComboBoxUI;
import com.sun.java.swing.plaf.windows.WindowsComboBoxUI;
import com.sunking.swing.JDatePicker;
import com.sunking.swing.OpenSwingUtil;
import com.sunking.swing.refer.JDateDocument;
import com.sunking.swing.refer.SingleObjectComboBoxModel;


/**
 * <p>日期选择控件 - 参考OpenSwing的JDatePicker。</p>
 * @author	Zeven
 * @version	1.0
 * @see		Object#equals(java.lang.Object)
 * @see		Object#hashCode()
 * @see		HashMap
 * @since	JDK1.4
 */

public class DatePicker extends JComboBox implements Serializable{
    /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
     * 日期格式类型
     */
    public static final int STYLE_CN_DATE = 0;
    public static final int STYLE_CN_DATE1 = 1;
    public static final int STYLE_CN_DATETIME = 2;
    public static final int STYLE_CN_DATETIME1 = 3;
    /**
     * 日期格式类型
     */
    private int formatStyle = STYLE_CN_DATE;
    /**
     * 当前设置日期格式
     */
    private SimpleDateFormat dateFormat = null;


    public static String[] weeks={"星期日","星期一","星期二","星期三",
                                  "星期四","星期五","星期六"};
    
    public static String constellation(Calendar cal){
  
                String [][]con ={
                     {"水瓶座","0122","0221"},
                     {"双鱼座","0222","0321"},
                     {"白羊座","0322","0420"},
                     {"金牛座","0421","0521"},
                     {"双子座","0522","0621"},
                     {"巨蟹座","0621","0721"},
                     {"狮子座","0722","0821"},
                     {"处女座","0822","0921"}, 
                     {"天秤座","0922","1021"},
                     {"天蝎座","1022","1121"},
                     {"射手座","1122","1221"},
                     {"摩羯座","1222","0121"}};
                int month=cal.get(Calendar.MONTH)+1;
                int today=cal.get(Calendar.DAY_OF_MONTH);
                String month_str=month<10?"0"+month:""+month;
                String today_str=today<10?"0"+today:""+today;
                String str=month_str+today_str;
                for( int i = 0 ; i < con.length-1 ; i++ )
                {
                     if(Integer.parseInt(str) >= Integer.parseInt(con[i][1]) && Integer.parseInt(str) <= Integer.parseInt(con[i][2]))
                        return con[i][0]; 
                 
                }
                if((Integer.parseInt(str) >= Integer.parseInt(con[11][1]) && Integer.parseInt(str) < 1232) ||  Integer.parseInt(str) <=Integer.parseInt( con[11][2]) )
                   return  con[11][0];
       
               return "error!";
        }
    
    /**
     * 只有一个值的ComboBoxModel
     */
    private SingleObjectComboBoxModel model = new SingleObjectComboBoxModel();
    JDateDocument dateDocument = null;
    /**
     * 构造式
     */
    public DatePicker() throws UnsupportedOperationException{
        this(STYLE_CN_DATE);
    }

    public DatePicker(int formatStyle) throws UnsupportedOperationException{
        this(formatStyle, new Date());
    }

    public DatePicker(int formatStyle, Date initialDatetime) throws
        UnsupportedOperationException{

        this.setStyle(formatStyle);
        //设置可编辑
        this.setEditable(true);
        //设置编辑器属性(只能输入正确日期)
        JTextField textField = ((JTextField)getEditor().getEditorComponent());
        textField.setHorizontalAlignment(SwingConstants.CENTER);
        dateDocument = new JDateDocument(textField, this.dateFormat);
        textField.setDocument(dateDocument);
        //设置Model为单值Model
        this.setModel(model);
        //设置当前选择日期
        this.setSelectedItem(initialDatetime == null ?
                             new Date() : initialDatetime);
    }

    /**
     * 设置日期格式
     *     STYLE_CN_DATE
     *     STYLE_CN_DATE1
     *     STYLE_CN_DATETIME
     *     STYLE_CN_DATETIME1
     * @param formatStyle int
     */
    public void setStyle(int formatStyle) throws UnsupportedOperationException{
        this.formatStyle = formatStyle;
        dateFormat = getDateFormat(formatStyle);
        model.setDateFormat(dateFormat);
        if(dateDocument != null){
            dateDocument.setDateFormat(dateFormat);
        }
    }

    /**
     * 取得指定类型的日期格式
     * @param formatStyle int
     * @return SimpleDateFormat
     * @throws UnsupportedOperationException
     */
    private static SimpleDateFormat getDateFormat(int formatStyle) throws
        UnsupportedOperationException{
        switch(formatStyle){
            case STYLE_CN_DATE:
                return new SimpleDateFormat("yyyy/MM/dd");
            case STYLE_CN_DATE1:
                return new SimpleDateFormat("yyyy-MM-dd");
            case STYLE_CN_DATETIME:
                return new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            case STYLE_CN_DATETIME1:
                return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            default:
                throw new UnsupportedOperationException(
                    "invalid formatStyle parameter!");
        }
    }

    /**
     * 取得日期格式
     *     STYLE_CN_DATE
     *     STYLE_CN_DATE1
     *     STYLE_CN_DATETIME
     *     STYLE_CN_DATETIME1
     * @return int
     */
    public int getStyle(){
        return formatStyle;
    }

    /**
     * 取得当前选择的日期
     * @return Date
     */
    public Date getSelectedDate() throws ParseException{
        return dateFormat.parse(getSelectedItem().toString());
    }

    /**
     * 设置当前选择的日期
     * @return Date
     */
    public void setSelectedDate(Date date) throws ParseException{
        this.setSelectedItem(dateFormat.format(date));
    }

    public void setSelectedItem(Object anObject){
        model.setSelectedItem(anObject);
        super.setSelectedItem(anObject);
    }

    /**
     * <p>Title: DatePicker</p>
     * <p>Description: DatePopup 选择框弹出的日期选择面板</p>
     * <p>Copyright: Copyright (c) 2004</p>
     * <p>Company: </p>
     * @author <a href="mailto:sunkingxie@hotmail.com"'>Sunking</a>
     * @version 1.0
     */
    class DatePopup extends BasicComboPopup implements ChangeListener{
        CalendarPanel calendarPanel = null;
        public DatePopup(JComboBox box){
            super(box);
            setLayout(new BorderLayout());
            calendarPanel = new CalendarPanel();
            calendarPanel.addDateChangeListener(this);
            add(calendarPanel, BorderLayout.CENTER);
            setBorder(BorderFactory.createEmptyBorder());
        }

        /**
         * 显示弹出面板
         */
        protected void firePropertyChange(String propertyName,
                                          Object oldValue,
                                          Object newValue){
            if(propertyName.equals("visible")){
                if(oldValue.equals(Boolean.FALSE)
                   && newValue.equals(Boolean.TRUE)){ //SHOW
                    try{
                        String strDate = comboBox.getSelectedItem().toString();
                        Date selectionDate = dateFormat.parse(strDate);
                        calendarPanel.setSelectedDate(selectionDate);
                    } catch(Exception ex){
                        ex.printStackTrace();
                    }
                } else if(oldValue.equals(Boolean.TRUE)
                          && newValue.equals(Boolean.FALSE)){ //HIDE
                }
            }
            super.firePropertyChange(propertyName, oldValue, newValue);
        }

        public void stateChanged(ChangeEvent e){
            Date selectedDate = (Date)e.getSource();
            String strDate = dateFormat.format(selectedDate);
            if(comboBox.isEditable() && comboBox.getEditor() != null){
                comboBox.configureEditor(comboBox.getEditor(), strDate);
            }
            comboBox.setSelectedItem(strDate);
            comboBox.setPopupVisible(false);
        }
    }

    /**
     * 更新UI
     */
    public void updateUI(){
        ComboBoxUI cui = (ComboBoxUI)UIManager.getUI(this);
        if(cui instanceof MetalComboBoxUI){
            cui = new MetalDateComboBoxUI();
        } else if(cui instanceof MotifComboBoxUI){
            cui = new MotifDateComboBoxUI();
        } else{
            cui = new WindowsDateComboBoxUI();
        }
        setUI(cui);
    }

    // UI Inner classes -- one for each supported Look and Feel
    /**
     * <p>Title: OpenSwing</p>
     * <p>Description: MetalDateComboBoxUI</p>
     * <p>Copyright: Copyright (c) 2004</p>
     * <p>Company: </p>
     * @author <a href="mailto:sunkingxie@hotmail.com">SunKing</a>
     * @version 1.0
     */
    class MetalDateComboBoxUI extends MetalComboBoxUI{
        protected ComboPopup createPopup(){
            return new DatePopup(comboBox);
        }
    }

    /**
     *
     * <p>Title: OpenSwing</p>
     * <p>Description: WindowsDateComboBoxUI</p>
     * <p>Copyright: Copyright (c) 2004</p>
     * <p>Company: </p>
     * @author <a href="mailto:sunkingxie@hotmail.com">SunKing</a>
     * @version 1.0
     */
    class WindowsDateComboBoxUI extends WindowsComboBoxUI{
        protected ComboPopup createPopup(){
            return new DatePopup(comboBox);
        }
    }

    /**
     *
     * <p>Title: OpenSwing</p>
     * <p>Description: MotifDateComboBoxUI</p>
     * <p>Copyright: Copyright (c) 2004</p>
     * <p>Company: </p>
     * @author <a href="mailto:sunkingxie@hotmail.com">SunKing</a>
     * @version 1.0
     */
    class MotifDateComboBoxUI extends MotifComboBoxUI{
        protected ComboPopup createPopup(){
            return new DatePopup(comboBox);
        }
    }

    /**
     * 测试DatePicker
     */
    public static void main(String args[]){

            JFrame f = OpenSwingUtil.createDemoFrame("DatePicker Demo");
            JPanel c = new JPanel();
            c.add(new JLabel("From:"));
            Date d = new Date();
            d.setTime(d.getTime() + 10000000000L);
            DatePicker datePickerFrom = new DatePicker(DatePicker.STYLE_CN_DATE, d);
            c.add(datePickerFrom);
            c.add(new JLabel("To:"));
            JDatePicker datePickerTo = new JDatePicker(); //JDatePicker.STYLE_CN_DATETIME
            datePickerTo.setEditable(false);
            c.add(datePickerTo);
            f.getContentPane().add(c, BorderLayout.NORTH);

            f.getContentPane().add(new JDatePicker(), BorderLayout.SOUTH);

            final JTable table = new JTable(20, 10);
            JComboBox editor = new DatePicker();
            editor.setBorder(null);
            table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
            table.setDefaultEditor(Object.class, new DefaultCellEditor(editor));
            JScrollPane sp = new JScrollPane(table);
            f.getContentPane().add(sp, BorderLayout.CENTER);

//            f.setSize(600, 400);
            f.setVisible(true);
    }
}
